#ifndef JSBACKEND_H
#define JSBACKEND_H

#include <QTextStream>
#include <QFile>
#include <QString>
#include <QList>
#include <QSet>

class Body;
class HtmlElement;
class Template;
class HtmlAttribute;
class Node;
class Var;
class Parameter;
class UserFunction;
class HtmlIf;
class PathOperator;
class MemberFunction;
class Component;
class Property;
class MemberEvent;
class MemberTemplate;
class QOptions;

class JSBackend
{
public:
    JSBackend(const QOptions* options);

    void run();

    void finish();

private:
    QString nextIdent();
    QString stringify(const QString& str) const;
    QString jsCSSName( HtmlAttribute* a, const QString& name );

    void generateTemplateBody(Template* t);
    void generateHtmlBody_Pass1(Body* body, QTextStream& out);
    void generateHtmlBody_Pass2(Body* body, QTextStream& out, QString finalStatement);
    void generateHtmlBody_Pass3(Body* body, QTextStream& out);
    void generateHtmlBody_Pass4(Body* body, QTextStream& out);
    void generateHtmlElement_Pass1(HtmlElement* element, QTextStream& out);
    void generateHtmlElement_Pass2(HtmlElement* element, QTextStream& out);
    void generateExpression( Node* expr, QTextStream& out );
    void generateVarInitialization(Var* v);
    QString generatePath( PathOperator*op, QTextStream& out );
    QSet<Parameter*> parametersUsed(Node* e);
    void parametersUsed(Node* e, QSet<Parameter*>& lst);
    QSet<Parameter*> parametersDeclared(Node* e);
    void parametersDeclared(Node* e, QSet<Parameter*>& lst);
    void generateUserFunction(UserFunction* f);
    void generateMemberFunction(MemberFunction *f);
    void generateProperty(Property* p);
    void generateComponent(Component* c);
    void generateEvent(MemberEvent* e);
    void generateMemberTemplate(MemberTemplate* m);
    void transformIf( HtmlIf* f );
    QString parametersUsedInExpression(Node* e);
    void parentExpressions(Node* e, QSet<QString>& result);

    QTextStream m_mainOutDecl;
    QTextStream m_mainOutDef;
    QTextStream m_out;
    QFile m_fileOut;
    int m_identCount;
    const QOptions* m_options;
};

#endif // JSBACKEND_H
